<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>预解析</title>
    <script>
        // 预解析的引入
        // 1问
        // console.log(num);

        // 2问
        console.log(num); // undefined 疑问1
        var num = 666;

        // 3问
        fun();
        function fun() {
            console.log(11);
        }
        // 4问
        // foo();报错  疑问2
        var foo = function () {
            console.log(22);
        }

        // JS解析器运行JS代码分两步：预解析和代码执行
        // 变量提升1
        console.log(num); // undefined 疑问1
        var num = 666;
        /* 相当于执行了以下的代码：
        var num;
        console.log(num);
        num = 666;
         */
        // 变量提升2
        foo();
        var foo = function () {
            console.log(22);
        }
        // 函数表达式 调用必须写在函数表达式的下面
        /* 相当于执行了以下的代码:
        var foo;
        foo();
        foo = function () {
            console.log(22);
        } */
        // 函数提升
        fun();
        function fun() {
            console.log(11);
        }


        // 预解析案例
        var num = 10;
        fun11();
        function fun11() {
            console.log(num);
            var num = 666;
        }
        // 相当于执行了以下的代码：
        /* 
        var num;
        function fun11() {
            var num;
            console.log(num);
            num = 666;
        }
        num = 10;
        fun11(); */

        // 案例2
        var num = 100;
        function far() {
            console.log(num);
            var num = 1000;
            console.log(num);
        }
        far();
        // 相当于执行了以下的代码：
        /* 
        var num;
        function far() {
            var num;
            console.log(num);
            num = 1000;
            console.log(num);
        } 
        far();
        */

        // 案例3
        var a = 18;
        f1();
        function f1() {
            var b = 9;
            console.log(a);
            console.log(b);
            var a = '123';
        }
        // 相当于执行了以下的代码：
       /*  
        var a;
        function f1() {
            var b;
            var a;
            b = 9;
            console.log(a);
            console.log(b);
            a = '123';
        }
        a = 18;
        f1(); */


        // 案例4
        f2();
        console.log(c);
        console.log(b);
        console.log(a);
        function f2() {
            var a = b = c = 9;
            console.log(a);
            console.log(b);
            console.log(c);
        }
        // 相当于执行了以下的代码：
       /*  
       function f2() {
            var a;
            a = b = c = 9;
            // 这里相当于var a = 9; b = 9; c = 9; b和c直接赋值，没有var声明。因此，b和c当全局变量看待
            // 集体声明：var a = 9, b = 9, c = 9;
            console.log(a);
            console.log(b);
            console.log(c);
        }
        f2();
        console.log(c);
        console.log(b);
        console.log(a); */
        
    </script>
</head>

<body>

</body>

</html>